package com.rowline.admin.module.util.utils;

import javax.xml.bind.*;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

/**
 * @author 李鹏飞
 * @version V1.0
 * @Description
 * @Time 2013-5-25
 */
public class JAXBUtil {

	 /**
	  * 反列化string——>object
	  *
	  * @param message
	  * @param clazz
	  * @return
	  * @throws UnsupportedEncodingException
	  * @throws JAXBException
	  * @Date 2016-04-18 补充注释
	  */
	public static final <T> T unmarshaller(String message, Class<T> clazz) throws UnsupportedEncodingException, JAXBException
			 {
		JAXBContext context = null;
		try {
			context = JAXBContext.newInstance(clazz);
			ByteArrayInputStream stream = new ByteArrayInputStream(
					message.getBytes("UTF-8"));
			InputStreamReader reader = new InputStreamReader(stream, "UTF-8");
			Unmarshaller unmarshaller = context.createUnmarshaller();
			JAXBElement<T> element = unmarshaller.unmarshal(new StreamSource(
					reader), clazz);
			return element.getValue();
		} catch (JAXBException e) {
			throw new JAXBException("反序列化" + clazz.getName() + "时失败！", e);
		}
	}
	 /**
     * 反列化InputStream——>object
     * 
     * @param inputStream
     * @param clazz
     * @return
     * @throws UnsupportedEncodingException
     * @throws JAXBException
     * @Date 2016-04-18 补充注释
     */
	public static final <T> T unmarshaller(InputStream inputStream,
			Class<T> clazz) throws UnsupportedEncodingException, JAXBException {
		try {
			JAXBContext context = JAXBContext.newInstance(clazz);
			InputStreamReader reader = new InputStreamReader(inputStream,
					"UTF-8");
			Unmarshaller unmarshaller = context.createUnmarshaller();
			JAXBElement<T> element = unmarshaller.unmarshal(new StreamSource(
					reader), clazz);
			return element.getValue();
		} catch (JAXBException e) {
			throw new JAXBException("反序列化" + clazz.getName() + "时失败！", e);
		}
	}
    /**
     * object->String 序列化
     * @param object
     * @param element
     * @return
     * @throws JAXBException
     * @Date 2016-04-18 补充注释
     */
	public static <T> String marshaller(T object, JAXBElement<T> element) throws JAXBException
			 {
		if (object == null) {
			return null;
		}
		JAXBContext context = null;
		try {
			context = JAXBContext.newInstance(object.getClass());
			StringWriter stringWriter = new StringWriter();
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING,
					"UTF-8");
			marshaller.marshal(element, stringWriter);
			stringWriter.flush();
			return stringWriter.toString();
		} catch (PropertyException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (FactoryConfigurationError e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (JAXBException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		}
	}

	  /**
     * object->String 序列化
     * @param object
     * @return
     * @throws JAXBException
     * @Date 2016-04-18 补充注释
     */
	public static <T> String marshaller(T object) throws JAXBException {
		if (object == null) {
			return null;
		}
		JAXBContext context = null;
		try {
			context = JAXBContext.newInstance(object.getClass());
			StringWriter stringWriter = new StringWriter();
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING,
					"UTF-8");
			marshaller.marshal(object, stringWriter);
			stringWriter.flush();
			return stringWriter.toString();
		} catch (PropertyException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (FactoryConfigurationError e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (JAXBException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		}
	}
     /**
      * * object->String 序列化
      * @param object
      * @param encoding
      * @return
      * @throws JAXBException
      * @Date 2016-04-18 补充注释
      */
	public static <T> String marshaller(T object, String encoding) throws JAXBException
			 {
		if (object == null) {
			return null;
		}
		JAXBContext context = null;
		try {
			context = JAXBContext.newInstance(object.getClass());
			StringWriter stringWriter = new StringWriter();
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING,
					encoding);
			marshaller.marshal(object, stringWriter);
			stringWriter.flush();
			return stringWriter.toString();
		} catch (PropertyException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (FactoryConfigurationError e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		} catch (JAXBException e) {
			throw new JAXBException("序列化" + object.getClass().getName()
					+ "时失败！", e);
		}
	}
	
	/**
	 * 响应Bean转为XML格式化的方法 ZHOUXI 2014-12-30
	 */
	public static String convertToXml(Object obj, String encoding) {
		String result = null;
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);

			StringWriter writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}
	
	/**
	 * XML格式字符串转为请求Bean的方法 ZHOUXI 2014-12-30
	 */
	@SuppressWarnings("unchecked")
	public static <T> T converyToJavaBean(String xml, Class<T> c) {
		T t = null;
		try {
			JAXBContext context = JAXBContext.newInstance(c);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			t = (T) unmarshaller.unmarshal(new StringReader(xml));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}
	
}
